import math

"""
区间筛法采用“先筛出小于等于√b的所有素数，然后利用这些素数去标记区间[a，b]内的合
数(非素数)，最后统计区间内剩余的素数个数”的策略：
1.合数的最小质因数性质：任何一个合数n都至少有一个小于等于√n的质因数。这是因为如果 n
是合数，那么它可以写成两个正整数p和q的乘积，即n=p×q。假设p>√n且q>√n 
，那么p×q>√n×√n=n，这与n=p× q矛盾。所以，p和q中至少有一个小于等于 Vn。
基于这个性质，对于区间[a，b]内的任意合数，它的最小质因数必然小于等于√b。因此，只要我们
找出了小于等于√Б的所有素数，就可以用这些素数来标记区间[a，b内的合数。
"""

# 读取输入的区间 [a, b]
a, b = map(int, input().split())

# 先筛出小于等于 sqrt(b) 的所有素数
sqrt_b = int(math.sqrt(b))
is_prime_small = [True] * (sqrt_b + 1)
is_prime_small[0] = is_prime_small[1] = False
primes_small = []

for i in range(2, sqrt_b + 1):
    # 当前没被标记，是质数
    if is_prime_small[i]:
        # 素数区间
        primes_small.append(i)
        # 以i为步长  去标记 能整除i的数（合数）
        for j in range(i * i, sqrt_b + 1, i):
            is_prime_small[j] = False

# 初始化区间 True，表示全是素数
is_prime = [True] * (b - a + 1)

# 用筛到的素数 去 筛区间[a,b]内的合数，
for prime in primes_small:
    # 找到 prime 在区间 [a, b] 内的最小倍数，使用 math.ceil 实现向上取整
    start = int(math.ceil(a / prime)) * prime
    for j in range(start, b + 1, prime):
        # 将 prime 的倍数（即合数）在 is_prime 列表中对应的位置设为 False，标记为不是素数
        is_prime[j - a] = False

# 统计区间 [a, b] 内的素数个数
ans = sum(is_prime)

# 输出结果
print(ans)
